package com.cloudwise.truelicensespringbootstarter.license.common;

import com.cloudwise.truelicensespringbootstarter.license.model.LicenseExtraModel;
import de.schlichtherle.license.*;
import de.schlichtherle.xml.GenericCertificate;
import de.schlichtherle.xml.XMLConstants;
import lombok.extern.slf4j.Slf4j;

import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;

/**
 * licenseManager扩展，可以校验自定义参数
 *
 * @see com.cloudwise.truelicensespringbootstarter.license.model.LicenseExtraModel
 * @author jeffery.li
 * @date 2022/6/8 16:57
 */
@Slf4j
public class CustomLicenseManager extends LicenseManager {

    public CustomLicenseManager(LicenseParam param){
        super(param);
    }

    @Override
    protected synchronized byte[] create(LicenseContent content, LicenseNotary notary) throws Exception {
        super.initialize(content);
        this.validate(content);
        final GenericCertificate certificate = notary.sign(content);
        return getPrivacyGuard().cert2key(certificate);
    }

    /**
     * 复写install方法，其中validate方法调用本类中的validate方法，校验IP地址、Mac地址等其他信息
     */
    @Override
    protected synchronized LicenseContent install(final byte[] key, final LicenseNotary notary) throws Exception {
        final GenericCertificate certificate = getPrivacyGuard().key2cert(key);
        notary.verify(certificate);
        final LicenseContent content = (LicenseContent) this.load(certificate.getEncoded());
        this.validate(content);
        super.setLicenseKey(key);
        super.setCertificate(certificate);
        return content;
    }


    @Override
    protected synchronized void validate(final LicenseContent content) throws LicenseContentException {

        //1. 首先调用父类的validate方法
        super.validate(content);
        //2. 然后校验自定义的License参数，去校验我们的license信息
        LicenseExtraModel expectedCheckModel = (LicenseExtraModel) content.getExtra();
        // 做我们自定义的校验
    }

    /**
     * 复写verify方法，调用本类中的validate方法，校验IP地址、Mac地址等其他信息
     */
    @Override
    protected synchronized LicenseContent verify(final LicenseNotary notary) throws Exception {

        GenericCertificate certificate = super.getCertificate();
        if (null != certificate)
            return (LicenseContent) certificate.getContent();

        // Load license key from preferences,
        final byte[] key = getLicenseKey();
        if (null == key)
            throw new NoLicenseInstalledException(super.getLicenseParam().getSubject());
        certificate = getPrivacyGuard().key2cert(key);
        notary.verify(certificate);
        final LicenseContent content = (LicenseContent) certificate.getContent();
        this.validate(content);
        setCertificate(certificate);

        return content;

    }

    /**
     * 重写XMLDecoder解析XML
     */
    private Object load(String encoded) {
        BufferedInputStream inputStream = null;
        XMLDecoder decoder = null;
        try {
            inputStream = new BufferedInputStream(new ByteArrayInputStream(encoded.getBytes(XMLConstants.XML_CHARSET)));
            decoder = new XMLDecoder(new BufferedInputStream(inputStream, XMLConstants.DEFAULT_BUFSIZE), null, null);
            return decoder.readObject();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } finally {
            try {
                if (decoder != null) {
                    decoder.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception e) {
                log.error("XMLDecoder解析XML失败", e);
            }
        }

        return null;
    }

}
